﻿namespace Centido.Core.Test
{
    using System;
    using System.Data.Common;
    using System.Linq;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    /// <summary>
    /// Testing roles
    /// </summary>
    [TestClass]
    public class RoleTest
    {
        /// <summary>
        /// Domain name
        /// </summary>
        public const string DomainName = "FullAdminRights";

        /// <summary>
        /// Domain
        /// </summary>
        private Domain _domain;

        /// <summary>
        /// Test initialize
        /// </summary>
        [TestInitialize]
        public void TestInitialize()
        {
            _domain = Domain.Build(DomainConfiguration.Load(DomainName));
            _domain.HasRecycleBin = new Random(Environment.TickCount).Next() % 2 == 1;

            _domain.DeleteAllRoles();
            _domain.DeleteAllUsers();
        }

        /// <summary>
        /// Test cleanup
        /// </summary>
        [TestCleanup]
        public void TestCleanup()
        {
            _domain.DeleteAllRoles();
            _domain.DeleteAllUsers();
        }

        /// <summary>
        /// Creating a role
        /// </summary>
        [TestMethod]
        public void CreatingRole()
        {
            var initialPrincipalCount = _domain.Principals.Count();

            // Creating a new role
            var roleName = StringProperty.RandomIdentifier();

            var role = _domain.AddRole(roleName);

            Assert.IsNotNull(role);
            Assert.AreEqual(role.Name, roleName.ToLower());

            Assert.IsTrue(role.Exists());
            
            Assert.AreEqual(_domain.Roles.Count(), 1);
            Assert.AreEqual(_domain.Roles.Count(r => r.Name == roleName.ToLower()), 1);

            Assert.AreEqual(_domain.Principals.Count(), initialPrincipalCount + 1);
            Assert.AreEqual(_domain.Principals.Count(p => p.Name == roleName.ToLower()), 1);

            Assert.IsNotNull(_domain.GetRole(roleName));
            Assert.AreEqual(_domain.GetRole(roleName).Name, roleName.ToLower());
        }


        /// <summary>
        ///   Creating the same role twice (to check that the platform handles the
        /// situation when the role is not removed after deleting).
        /// </summary>
        [TestMethod]
        public void CreatingRoleTwice()
        {
            // Creating a new role
            var roleName = StringProperty.RandomIdentifier();

            var role = _domain.AddRole(roleName);

            Assert.IsNotNull(role);
            Assert.IsTrue(role.Exists());

            // Removing that role
            role.Delete();

            Assert.IsFalse(role.Exists());

            // Creating that role again
            role = _domain.AddRole(roleName);

            Assert.IsNotNull(role);
            Assert.IsTrue(role.Exists());
        }

        /// <summary>
        /// Creating role with duplicate name
        /// </summary>
        [TestMethod]
        public void CreatingRoleWithDuplicateName()
        {
            var firstRole = _domain.AddRole(StringProperty.RandomIdentifier());

            try
            {
                _domain.AddRole(firstRole.Name);
            }
            catch (DbException e)
            {
                Assert.AreEqual(e.GetErrorCode(), DbErrorCode.AddingRoleWithDuplicateName);
                return;
            }

            Assert.Fail();
        }

        /// <summary>
        /// Passing null when creating a role
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof(ArgumentException), AllowDerivedTypes = true)]
        public void PassingNullWhenCreatingRole()
        {
            _domain.AddRole(null);
        }

        /// <summary>
        /// Passing empty string when creating a role
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof(ArgumentException), AllowDerivedTypes = true)]
        public void PassingEmtryStringWhenCreatingRole()
        {
            _domain.AddRole("  ");
        }

        /// <summary>
        /// Passing non-identifier when creating a role
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof(ArgumentException), AllowDerivedTypes = true)]
        public void PassingNonIdentifierWhenCreatingRole()
        {
            _domain.AddRole("1a");
        }

        /// <summary>
        /// Passing a keyword when creating a role
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof(ArgumentException), AllowDerivedTypes = true)]
        public void PassingKeywordWhenCreatingRole()
        {
            _domain.AddRole("select");
        }

        /// <summary>
        /// Passing too long name when creating a role
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof(ArgumentException), AllowDerivedTypes = true)]
        public void PassingTooLongNameWhenCreatingRole()
        {
            _domain.AddRole(StringProperty.TooLongIdentifier('a'));
        }

        /// <summary>
        /// Checking that role name is lowered and trimmed
        /// </summary>
        [TestMethod]
        public void CheckingThatRoleNameIsLoweredAndTrimmed()
        {
            var role = _domain.AddRole("\t A\t ");

            Assert.AreEqual(role.Name, "a");
        }

        /// <summary>
        /// Reading and writing role display name
        /// </summary>
        [TestMethod]
        public void ReadingAndWritingRoleDisplayName()
        {
            var role = _domain.AddRole(StringProperty.RandomIdentifier());

            Assert.IsNull(role.DisplayName);

            //Setting display name
            role.DisplayName = StringProperty.StandardValue('A');

            Assert.AreEqual(role.DisplayName, StringProperty.StandardValue('A'));

            //Setting display name to null
            role.DisplayName = null;

            Assert.IsNull(role.DisplayName);
        }

        /// <summary>
        /// Writing too long display name
        /// </summary>
        [TestMethod]
        public void WritingTooLongDisplayName()
        {
            var role = _domain.AddRole(StringProperty.RandomIdentifier());

            try
            {
                role.DisplayName = StringProperty.TooLongStandardValue('A');
            }
            catch (DbException)
            {
                Assert.IsNull(role.DisplayName);
                return;
            }

            Assert.Fail();
        }

        /// <summary>
        /// Adding role in role
        /// </summary>
        [TestMethod]
        public void AddingRoleInRole()
        {
            var role = _domain.AddRole(StringProperty.RandomIdentifier());

            var anotherRole = _domain.AddRole(StringProperty.RandomIdentifier());

            Assert.AreEqual(_domain.Roles.Count(), 2);
            Assert.AreEqual(role.ChildRoles.Count(), 0);
            Assert.AreEqual(role.Principals.Count(), 0);
            Assert.AreEqual(anotherRole.ParentRoles.Count(), 0);

            //Adding role in role
            role.AddRole(anotherRole);

            Assert.AreEqual(role.ChildRoles.Count(), 1);
            Assert.AreEqual(role.ChildRoles.Count(r => r.Name == anotherRole.Name), 1);
            Assert.AreEqual(role.Principals.Count(), 1);
            Assert.AreEqual(role.Principals.Count(p => p.Name == anotherRole.Name), 1);
            Assert.IsTrue(role.ContainsRole(anotherRole.Name));

            Assert.AreEqual(anotherRole.ParentRoles.Count(), 1);
            Assert.AreEqual(anotherRole.ParentRoles.Count(r => r.Name == role.Name), 1);
        }

        /// <summary>
        /// Adding non existent role in role
        /// </summary>
        [TestMethod]
        public void AddingNonexistentRoleInRole()
        {
            var child = _domain.AddRole(StringProperty.RandomIdentifier());
            var parent = _domain.AddRole(StringProperty.RandomIdentifier());

            child.Delete();

            try
            {
                parent.AddRole(child);
            }
            catch (DbException e)
            {
                Assert.AreEqual(e.GetErrorCode(), DbErrorCode.RoleWasNotFound);
                return;
            }

            Assert.Fail();
        }

        /// <summary>
        /// Adding role in nonexistent role
        /// </summary>
        [TestMethod]
        public void AddingRoleInNonexistentRole()
        {
            var child = _domain.AddRole(StringProperty.RandomIdentifier());
            var parent = _domain.AddRole(StringProperty.RandomIdentifier());

            parent.Delete();

            try
            {
                parent.AddRole(child);
            }
            catch (DbException e)
            {
                Assert.AreEqual(e.GetErrorCode(), DbErrorCode.RoleWasNotFound);
                return;
            }

            Assert.Fail();
        }

        /// <summary>
        /// Forming cycle of roles
        /// </summary>
        [TestMethod]
        public void FormingCycleOfRoles()
        {
            var firstChild = _domain.AddRole(StringProperty.RandomIdentifier());
            var secondChild = _domain.AddRole(StringProperty.RandomIdentifier());
            var parent = _domain.AddRole(StringProperty.RandomIdentifier());
            var baseChild = _domain.AddRole(StringProperty.RandomIdentifier());

            firstChild.AddRole(baseChild);
            secondChild.AddRole(baseChild);
            parent.AddRole(firstChild);
            parent.AddRole(secondChild);

            Assert.AreEqual(parent.ChildRoles.Count(), 2);
            Assert.AreEqual(firstChild.ChildRoles.Count(), 1);
            Assert.AreEqual(firstChild.ParentRoles.Count(), 1);
            Assert.AreEqual(secondChild.ChildRoles.Count(), 1);
            Assert.AreEqual(secondChild.ParentRoles.Count(), 1);
            Assert.AreEqual(baseChild.ParentRoles.Count(), 2);
        }

        /// <summary>
        /// Passing null when adding role in role
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof(ArgumentException), AllowDerivedTypes = true)]
        public void PassingNullWhenAddingRoleInRole()
        {
            var role = _domain.AddRole(StringProperty.RandomIdentifier());

            role.AddRole(roleToAddName: null);
        }

        /// <summary>
        /// Passing invalid role name when adding role in role
        /// </summary>
        [TestMethod]
        public void PassingInvalidRoleNameWhenAddingRoleInRole()
        {
            var role = _domain.AddRole(StringProperty.RandomIdentifier());

            try
            {
                role.AddRole(StringProperty.RandomIdentifier());
            }
            catch (DbException)
            {
                Assert.AreEqual(role.ChildRoles.Count, 0);
                return;
            }

            Assert.Fail();
        }

        /// <summary>
        /// Adding role in the same role
        /// </summary>
        [TestMethod]
        public void AddingRoleInTheSameRole()
        {
            var role = _domain.AddRole(StringProperty.RandomIdentifier());

            try
            {
                role.AddRole(role);
            }
            catch (DbException)
            {
                Assert.AreEqual(role.ChildRoles.Count, 0);
                return;
            }

            Assert.Fail();
        }

        /// <summary>
        /// Adding role in role twice
        /// </summary>
        [TestMethod]
        public void AddingRoleInRoleTwice()
        {
            var role = _domain.AddRole(StringProperty.RandomIdentifier());

            var anotherRole = _domain.AddRole(StringProperty.RandomIdentifier());

            role.AddRole(anotherRole);

            Assert.AreEqual(role.ChildRoles.Count(), 1);

            try
            {
                role.AddRole(anotherRole);
            }
            catch (DbException e)
            {
                Assert.AreEqual(e.GetErrorCode(), DbErrorCode.AddingRoleInRoleTwice);
                return;
            }

            Assert.Fail();
        }

        /// <summary>
        /// Building cycle of two roles
        /// </summary>
        [TestMethod]
        public void BuildingCycleOfTwoRoles()
        {
            var role = _domain.AddRole(StringProperty.RandomIdentifier());
            var anotherRole = _domain.AddRole(StringProperty.RandomIdentifier());

            role.AddRole(anotherRole);

            try
            {
                anotherRole.AddRole(role);
            }
            catch (DbException)
            {
                Assert.AreEqual(anotherRole.ChildRoles.Count, 0); // Bug fix
                return;
            }

            Assert.Fail();
        }

        /// <summary>
        /// Building cycle of three roles
        /// </summary>
        [TestMethod]
        public void BuildingCycleOfThreeRoles()
        {
            var firstRole = _domain.AddRole(StringProperty.RandomIdentifier());
            var secondRole = _domain.AddRole(StringProperty.RandomIdentifier());
            var thirdRole = _domain.AddRole(StringProperty.RandomIdentifier());

            firstRole.AddRole(secondRole);
            secondRole.AddRole(thirdRole);

            try
            {
                thirdRole.AddRole(firstRole);
            }
            catch (DbException)
            {
                Assert.AreEqual(thirdRole.ChildRoles.Count, 0); // Bug fix
                return;
            }

            Assert.Fail();
        }

        /// <summary>
        /// Deleting role from role
        /// </summary>
        [TestMethod]
        public void DeletingRoleFromRole()
        {
            var firstRole = _domain.AddRole(StringProperty.RandomIdentifier());
            var secondRole = _domain.AddRole(StringProperty.RandomIdentifier());

            firstRole.AddRole(secondRole.Name);

            Assert.AreEqual(firstRole.ChildRoles.Count(), 1);
            Assert.AreEqual(secondRole.ParentRoles.Count(), 1);

            //Deleting role from role
            firstRole.RemoveRole(secondRole);

            Assert.AreEqual(firstRole.ChildRoles.Count(), 0);
            Assert.AreEqual(firstRole.Principals.Count(), 0);
            Assert.IsFalse(firstRole.ContainsRole(secondRole.Name));

            Assert.AreEqual(secondRole.ParentRoles.Count(), 0);
        }

        /// <summary>
        /// Passing null when deleting role from role
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof(ArgumentException), AllowDerivedTypes = true)]
        public void PassingNullWhenDeletingRoleFromRole()
        {
            var firstRole = _domain.AddRole(StringProperty.RandomIdentifier());

            firstRole.RemoveRole(roleToDeleteName: null);
        }

        /// <summary>
        /// Deleting not enrolled role from role
        /// </summary>
        [TestMethod]
        public void DeletingNotEnrolledRoleFromRole()
        {
            var parent = _domain.AddRole(StringProperty.RandomIdentifier());

            var child = _domain.AddRole(StringProperty.RandomIdentifier());

            try
            {
                parent.RemoveRole(child);
            }
            catch (DbException e)
            {
                Assert.AreEqual(e.GetErrorCode(), DbErrorCode.RoleEnrollmentWasNotFound);
                return;
            }

            Assert.Fail();
        }

        /// <summary>
        /// Deleting nonexistent role from role
        /// </summary>
        [TestMethod]
        public void DeletingNonexistentRoleFromRole()
        {
            var child = _domain.AddRole(StringProperty.RandomIdentifier());
            var parent = _domain.AddRole(StringProperty.RandomIdentifier());

            parent.AddRole(child);

            child.Delete();

            try
            {
                parent.RemoveRole(child);
            }
            catch (DbException e)
            {
                Assert.AreEqual(e.GetErrorCode(), DbErrorCode.RoleWasNotFound);
                return;
            }

            Assert.Fail();
        }

        /// <summary>
        /// Deleting role from nonexistent role
        /// </summary>
        [TestMethod]
        public void DeletingRoleFromNonexistentRole()
        {
            var child = _domain.AddRole(StringProperty.RandomIdentifier());
            var parent = _domain.AddRole(StringProperty.RandomIdentifier());

            parent.AddRole(child);

            parent.Delete();

            try
            {
                parent.RemoveRole(child);
            }
            catch (DbException e)
            {
                Assert.AreEqual(e.GetErrorCode(), DbErrorCode.RoleWasNotFound);
                return;
            }

            Assert.Fail();
        }

        /// <summary>
        /// Checking that deleted role is deleted from role
        /// </summary>
        [TestMethod]
        public void CheckingThatDeletedRoleIsDeletedFromRole()
        {
            var firstRole = _domain.AddRole(StringProperty.RandomIdentifier());

            var secondRole = _domain.AddRole(StringProperty.RandomIdentifier());

            firstRole.AddRole(secondRole);

            Assert.AreEqual(firstRole.ChildRoles.Count(), 1);

            //Deleting the second role
            secondRole.Delete();

            Assert.AreEqual(firstRole.ChildRoles.Count(), 0);
        }


        /// <summary>
        ///   Checking that a role contains another role (bug fix)
        /// </summary>
        [TestMethod]
        public void CheckingThatRoleContainsRole()
        {
            var firstRole = _domain.AddRole(StringProperty.RandomIdentifier());
            var secondRole = _domain.AddRole(StringProperty.RandomIdentifier());
            var thirdRole = _domain.AddRole(StringProperty.RandomIdentifier());

            firstRole.AddRole(secondRole);

            Assert.IsTrue(firstRole.ContainsRole(secondRole));
            Assert.IsFalse(firstRole.ContainsRole(thirdRole));
        }

        /// <summary>
        /// Adding user in role
        /// </summary>
        [TestMethod]
        public void AddingUserInRole()
        {
            var role = _domain.AddRole(StringProperty.RandomIdentifier());

            var user = _domain.AddUser(StringProperty.RandomIdentifier(), StringProperty.RandomPassword());

            Assert.AreEqual(role.Users.Count(), 0);
            Assert.AreEqual(role.Principals.Count(), 0);

            Assert.AreEqual(user.Roles.Count(), 0);

            role.AddUser(user);

            Assert.AreEqual(role.Users.Count(), 1);
            Assert.AreEqual(role.Users.Count(u => u.Name == user.Name), 1);
            Assert.AreEqual(role.Principals.Count(), 1);
            Assert.AreEqual(role.Principals.Count(p => p.Name == user.Name), 1);
            Assert.IsTrue(role.ContainsUser(user.Name));

            Assert.AreEqual(user.Roles.Count(), 1);
            Assert.AreEqual(user.Roles.Count(r => r.Name == role.Name), 1);
        }

        /// <summary>
        /// Passing null when adding user in role
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof(ArgumentException), AllowDerivedTypes = true)]
        public void PassingNullWhenAddingUserInRole()
        {
            var role = _domain.AddRole(StringProperty.RandomIdentifier());

            role.AddUser(userName: null);
        }

        /// <summary>
        /// Adding user in role twice
        /// </summary>
        [TestMethod]
        public void AddingUserInRoleTwice()
        {
            var role = _domain.AddRole(StringProperty.RandomIdentifier());

            var user = _domain.AddUser(StringProperty.RandomIdentifier(), StringProperty.RandomPassword());

            role.AddUser(user);

            try
            {
                role.AddUser(user);
            }
            catch (DbException e)
            {
                Assert.AreEqual(e.GetErrorCode(), DbErrorCode.AddingUserInRoleTwice);
                Assert.AreEqual(role.Users.Count, 1);
                return;
            }

            Assert.Fail();
        }

        /// <summary>
        /// Adding nonexistent user in role
        /// </summary>
        [TestMethod]
        public void AddingNonExistentUserInRole()
        {
            var role = _domain.AddRole(StringProperty.RandomIdentifier());

            var user = _domain.AddUser(StringProperty.RandomIdentifier(), StringProperty.RandomPassword());

            user.Delete();

            try
            {
                role.AddUser(user);
            }
            catch (DbException e)
            {
                Assert.AreEqual(e.GetErrorCode(), DbErrorCode.UserWasNotFound);
                return;
            }

            Assert.Fail();
        }

        /// <summary>
        /// Adding a user in a nonexistent role
        /// </summary>
        [TestMethod]
        public void AddingUserInNonexistentRole()
        {
            var role = _domain.AddRole(StringProperty.RandomIdentifier());

            var user = _domain.AddUser(StringProperty.RandomIdentifier(), StringProperty.RandomPassword());

            role.Delete();

            try
            {
                role.AddUser(user);
            }
            catch (DbException e)
            {
                Assert.AreEqual(e.GetErrorCode(), DbErrorCode.RoleWasNotFound);
                return;
            }

            Assert.Fail();
        }

        /// <summary>
        /// Deleting user from role
        /// </summary>
        [TestMethod]
        public void DeletingUserFromRole()
        {
            var role = _domain.AddRole(StringProperty.RandomIdentifier());

            var user = _domain.AddUser(StringProperty.RandomIdentifier(), StringProperty.RandomPassword());

            role.AddUser(user);

            Assert.AreEqual(role.Users.Count(), 1);
            Assert.AreEqual(user.Roles.Count(), 1);

            //Deleting user from role
            role.RemoveUser(user);

            Assert.AreEqual(role.Users.Count(), 0);
            Assert.AreEqual(role.Principals.Count(), 0);
            Assert.IsFalse(role.ContainsUser(user));

            Assert.AreEqual(user.Roles.Count(), 0);
        }


        /// <summary>
        ///   Checking that a role contains a user (bug fix)
        /// </summary>
        [TestMethod]
        public void CheckingThatRoleContainsUser()
        {
            var role = _domain.AddRole(StringProperty.RandomIdentifier());

            var firstUser = _domain.AddUser(StringProperty.RandomIdentifier(), StringProperty.RandomPassword());
            var secondUser = _domain.AddUser(StringProperty.RandomIdentifier(), StringProperty.RandomPassword());

            role.AddUser(firstUser);

            Assert.IsTrue(role.ContainsUser(firstUser));
            Assert.IsFalse(role.ContainsUser(secondUser.Name));
        }

        /// <summary>
        /// Passing null when deleting user from role
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof(ArgumentException), AllowDerivedTypes = true)]
        public void PassingNullWhenDeletingUserFromRole()
        {
            var role = _domain.AddRole(StringProperty.RandomIdentifier());

            role.RemoveUser(userName: null);
        }

        /// <summary>
        /// Deleting not enrolled user from role
        /// </summary>
        [TestMethod]
        public void DeletingNotEnrolledUserFromRole()
        {
            var role = _domain.AddRole(StringProperty.RandomIdentifier());

            var user = _domain.AddUser(StringProperty.RandomIdentifier(), StringProperty.RandomPassword());

            try
            {
                role.RemoveUser(user);
            }
            catch (DbException e)
            {
                Assert.AreEqual(e.GetErrorCode(), DbErrorCode.UserEnrollmentWasNotFound);
                return;
            }

            Assert.Fail();
        }

        /// <summary>
        /// Deleting nonexistent user from role
        /// </summary>
        [TestMethod]
        public void DeletingNonexistentUserFromRole()
        {
            var role = _domain.AddRole(StringProperty.RandomIdentifier());

            var user = _domain.AddUser(StringProperty.RandomIdentifier(), StringProperty.RandomPassword());

            role.AddUser(user);

            user.Delete();

            try
            {
                role.RemoveUser(user);
            }
            catch (DbException e)
            {
                Assert.AreEqual(e.GetErrorCode(), DbErrorCode.UserWasNotFound);
                return;
            }

            Assert.Fail();
        }

        /// <summary>
        /// Deleting user from nonexistent role
        /// </summary>
        [TestMethod]
        public void DeletingUserFromNonexistentRole()
        {
            var role = _domain.AddRole(StringProperty.RandomIdentifier());

            var user = _domain.AddUser(StringProperty.RandomIdentifier(), StringProperty.RandomPassword());

            role.AddUser(user);

            role.Delete();

            try
            {
                role.RemoveUser(user);
            }
            catch (DbException e)
            {
                Assert.AreEqual(e.GetErrorCode(), DbErrorCode.RoleWasNotFound);
                return;
            }

            Assert.Fail();
        }

        /// <summary>
        /// Checking that deleted user is deleted from role
        /// </summary>
        [TestMethod]
        public void CheckingThatDeletedUserIsDeletedFromRole()
        {
            var role = _domain.AddRole(StringProperty.RandomIdentifier());

            var user = _domain.AddUser(StringProperty.RandomIdentifier(), StringProperty.RandomPassword());

            role.AddUser(user);

            Assert.AreEqual(role.Users.Count(), 1);

            //Deleting the user
            user.Delete();

            Assert.AreEqual(role.Users.Count(), 0);
            Assert.AreEqual(role.Principals.Count(), 0);
        }

        /// <summary>
        /// Deleting a role
        /// </summary>
        [TestMethod]
        public void DeletingRoleByReference()
        {
            var role = _domain.AddRole(StringProperty.RandomIdentifier());

            Assert.AreEqual(_domain.Roles.Count(), 1);

            //Deleting the role
            _domain.DeleteRole(role);

            Assert.AreEqual(_domain.Roles.Count(), 0);
            Assert.IsNull(_domain.GetRole(role.Name));
            Assert.IsFalse(role.Exists());
        }

        /// <summary>
        /// Deleting role by name
        /// </summary>
        [TestMethod]
        public void DeletingRoleByName()
        {
            var role = _domain.AddRole(StringProperty.RandomIdentifier());

            Assert.AreEqual(_domain.Roles.Count(), 1);

            //Deleting the role
            _domain.DeleteRole(role.Name);

            Assert.AreEqual(_domain.Roles.Count(), 0);
            Assert.IsNull(_domain.GetRole(role.Name));
            Assert.IsFalse(role.Exists());
        }

        /// <summary>
        /// Writing properties of deleted role
        /// </summary>
        [TestMethod]
        [ExpectedException(typeof(DbException), AllowDerivedTypes = true)]
        public void WritingPropertiesOfDeletedRole()
        {
            var role = _domain.AddRole(StringProperty.RandomIdentifier());

            role.Delete();

            role.DisplayName = StringProperty.StandardValue('a');
        }

        /// <summary>
        /// Deleting role that was deleted
        /// </summary>
        [TestMethod]
        public void DeletingRoleThatWasDeleted()
        {
            var role = _domain.AddRole(StringProperty.RandomIdentifier());

            role.Delete();

            try
            {
                role.Delete();
            }
            catch (DbException e)
            {
                Assert.AreEqual(e.GetErrorCode(), DbErrorCode.RoleWasNotFound);
                return;
            }

            Assert.Fail();
        }
    }
}